<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>xeokit visual test</title>
    <link href="css/pageStyle.css" rel="stylesheet" />
  </head>

  <body>
    <canvas id="myCanvas"></canvas>
  </body>

  <script type="module">
    //------------------------------------------------------------------------------------------------------------------
    // Import the modules we need for this example
    //------------------------------------------------------------------------------------------------------------------

    import { Viewer, SceneModel } from "../../dist/xeokit-sdk.min.es.js";
    import { signalTestComplete } from "./lib/utils.js";

    //------------------------------------------------------------------------------------------------------------------
    // Create a Viewer and arrange the camera
    //------------------------------------------------------------------------------------------------------------------

    const viewer = new Viewer({
      canvasId: "myCanvas",
      transparent: true,
      dtxEnabled: true,
    });

    viewer.scene.camera.eye = [-21.8, 4.01, 6.56];
    viewer.scene.camera.look = [0, -5.75, 0];
    viewer.scene.camera.up = [0.37, 0.91, -0.11];

    //------------------------------------------------------------------------------------------------------------------
    // Create a SceneModel representing a table with four legs, using geometry batching
    //------------------------------------------------------------------------------------------------------------------

    const sceneModel = new SceneModel(viewer.scene, {
      id: "table",
      isModel: true, // <--------------------- Represents a model, registers SceneModel by ID on viewer.scene.models
      position: [0, 0, 0],
      scale: [1, 1, 1],
      rotation: [0, 0, 0],
      edges: true,
    });

    //-----------------------------------------------------------
    // Create a red table leg object
    // Each object is comprised of a mesh, which belongs to a node
    //-----------------------------------------------------------

    sceneModel.createMesh({
      id: "redLegMesh",

      // The primitive type - allowed values are "points", "lines" and "triangles".
      // See the OpenGL/WebGL specification docs for how the coordinate arrays are supposed to be laid out.
      primitive: "triangles",

      // The vertices - eight for our cube, each one spanning three array elements for X,Y and Z
      positions: [
        1,
        1,
        1,
        -1,
        1,
        1,
        -1,
        -1,
        1,
        1,
        -1,
        1, // v0-v1-v2-v3 front
        1,
        1,
        1,
        1,
        -1,
        1,
        1,
        -1,
        -1,
        1,
        1,
        -1, // v0-v3-v4-v1 right
        1,
        1,
        1,
        1,
        1,
        -1,
        -1,
        1,
        -1,
        -1,
        1,
        1, // v0-v1-v6-v1 top
        -1,
        1,
        1,
        -1,
        1,
        -1,
        -1,
        -1,
        -1,
        -1,
        -1,
        1, // v1-v6-v7-v2 left
        -1,
        -1,
        -1,
        1,
        -1,
        -1,
        1,
        -1,
        1,
        -1,
        -1,
        1, // v7-v4-v3-v2 bottom
        1,
        -1,
        -1,
        -1,
        -1,
        -1,
        -1,
        1,
        -1,
        1,
        1,
        -1, // v4-v7-v6-v1 back
      ],

      // Normal vectors, one for each vertex
      normals: [
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1, // v0-v1-v2-v3 front
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0, // v0-v3-v4-v5 right
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0,
        0,
        1,
        0, // v0-v5-v6-v1 top
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0, // v1-v6-v7-v2 left
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0, // v7-v4-v3-v2 bottom
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1,
        0,
        0,
        -1, // v4-v7-v6-v5 back
      ],

      // Indices - these organise the positions and and normals
      // into geometric primitives in accordance with the "primitive" parameter,
      // in this case a set of three indices for each triangle.
      //
      // Note that each triangle is specified in counter-clockwise winding order.
      //
      indices: [
        0,
        1,
        2,
        0,
        2,
        3, // front
        4,
        5,
        6,
        4,
        6,
        7, // right
        8,
        9,
        10,
        8,
        10,
        11, // top
        12,
        13,
        14,
        12,
        14,
        15, // left
        16,
        17,
        18,
        16,
        18,
        19, // bottom
        20,
        21,
        22,
        20,
        22,
        23,
      ],

      position: [-4, -6, -4],
      scale: [1, 3, 1],
      rotation: [0, 0, 0],
      color: [1, 0.3, 0.3],
    });

    sceneModel.createEntity({
      id: "redLeg",
      meshIds: ["redLegMesh"],
      isObject: true, // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
    });

    //--------------------------------------------------------
    // Green table leg object
    //--------------------------------------------------------

    sceneModel.createMesh({
      id: "greenLegMesh",
      primitive: "triangles",
      positions: [
        1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1,
        1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
        -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,
        -1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
      ],
      normals: [
        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
        0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,
        0, 0, -1,
      ],
      indices: [
        0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12,
        14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23,
      ],
      position: [4, -6, -4],
      scale: [1, 3, 1],
      rotation: [0, 0, 0],
      color: [0.3, 1.0, 0.3],
    });

    sceneModel.createEntity({
      id: "greenLeg",
      meshIds: ["greenLegMesh"],
      isObject: true, // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
    });

    //--------------------------------------------------------
    // Blue table leg object
    //--------------------------------------------------------

    sceneModel.createMesh({
      id: "blueLegMesh",
      positions: [
        1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1,
        1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
        -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,
        -1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
      ],
      normals: [
        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
        0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,
        0, 0, -1,
      ],
      indices: [
        0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12,
        14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23,
      ],
      position: [4, -6, 4],
      scale: [1, 3, 1],
      rotation: [0, 0, 0],
      color: [0.3, 0.3, 1.0],
    });

    sceneModel.createEntity({
      id: "blueLeg",
      meshIds: ["blueLegMesh"],
      isObject: true, // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
    });

    //--------------------------------------------------------
    // Yellow table leg object
    //--------------------------------------------------------

    sceneModel.createMesh({
      id: "yellowLegMesh",
      positions: [
        1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1,
        1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
        -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,
        -1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
      ],
      normals: [
        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
        0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,
        0, 0, -1,
      ],
      indices: [
        0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12,
        14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23,
      ],
      position: [-4, -6, 4],
      scale: [1, 3, 1],
      rotation: [0, 0, 0],
      color: [1.0, 1.0, 0.0],
    });

    sceneModel.createEntity({
      id: "yellowLeg",
      meshIds: ["yellowLegMesh"],
      isObject: true, // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
    });

    //--------------------------------------------------------
    // Purple table top object
    //--------------------------------------------------------

    sceneModel.createMesh({
      id: "purpleTableTopMesh",
      positions: [
        1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1,
        1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1,
        -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1,
        -1, -1, -1, -1, -1, 1, -1, 1, 1, -1,
      ],
      normals: [
        0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
        0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
        0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1,
        0, 0, -1,
      ],
      indices: [
        0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12,
        14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23,
      ],
      position: [0, -3, 0],
      scale: [6, 0.5, 6],
      rotation: [0, 0, 0],
      color: [1.0, 0.3, 1.0],
    });

    sceneModel.createEntity({
      id: "purpleTableTop",
      meshIds: ["purpleTableTopMesh"],
      isObject: true, // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
    });

    //------------------------------------------------------------
    // Finalize the SceneModel.
    //
    // Internally, this builds any geometry batches or instanced
    // arrays that are currently under construction within it.
    //------------------------------------------------------------

    sceneModel.finalize();

    //------------------------------------------------------------------------------------------------------------------
    // Find Entities by their IDs
    //------------------------------------------------------------------------------------------------------------------

    // Get the whole table model
    var table = viewer.scene.models["table"];

    // Get some leg objects
    var redLeg = viewer.scene.objects["redLeg"];
    var greenLeg = viewer.scene.objects["greenLeg"];
    var blueLeg = viewer.scene.objects["blueLeg"];

    //------------------------------------------------------------------------------------------------------------------
    // Mouse over Entities to highlight them
    //------------------------------------------------------------------------------------------------------------------

    var lastEntity = null;

    viewer.scene.input.on("mousemove", function (coords) {
      var hit = viewer.scene.pick({
        canvasPos: coords,
      });

      if (hit) {
        if (!lastEntity || hit.entity.id !== lastEntity.id) {
          if (lastEntity) {
            lastEntity.colorize = null;
          }

          lastEntity = hit.entity;
          lastEntity.colorize = [1.0, 0.0, 0.0];
        }
      } else {
        if (lastEntity) {
          lastEntity.colorize = null;
          lastEntity = null;
        }
      }
    });
    signalTestComplete(viewer);
  </script>
</html>
